<script lang="ts">
// @ts-nocheck
import {defineComponent, PropType} from 'vue'
import { RecycleScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
import {BindData} from "./Types.ts";
export default defineComponent({
  name: "VirtualScroller",
  components: {
    RecycleScroller,
  },
  props: {
    gridItems: {
      type: Number,
      default: () => 1
    },
    minSize: {
      type: Number,
    },
    list: {
      type: Array as PropType<any[]>,
      default: () => []
    },
    itemKey: {
      type: String,
    },
    fixed: {
      type: Boolean,
    },
    buffer: {
      type: Number,
      default: () => 200
    },
    listClass: {
      type: String,
      default: () => ''
    },
    itemClass: {
      type: String,
      default: () => ''
    },
    horizontal: {
      type: Boolean,
    },
  },
  computed: {
    direction() {
      if(this.horizontal) {
        return 'horizontal'
      } else {
        return 'vertical'
      }
    }
  },
  methods: {
    getScollerEl() {
      let RecycleScroller = this.$refs.RecycleScrollerRef
      if(RecycleScroller){
        let el = RecycleScroller.$el
        return el
      }
      return null
    },
    itemSecondarySize(height, width) {
      if(!this.gridItems) {
        return null
      }
      if(this.direction === 'vertical') {
        return width / this.gridItems
      }else {
        return height / this.gridItems
      }
    },
    getBuffer() {
      if(this.minSize>0) {
        return this.buffer * this.minSize
      }
      return this.buffer * 50
    },
    scrollIntoView(index:number) {
      let el = this.getScollerEl()
      if(el) {
        let value = index * this.minSize / this.gridItems
        if(this.direction === 'vertical') {
          value = value - (el.offsetHeight / 2 - this.minSize / 2)
          el.scrollTo({
            top: value,
            behavior: "smooth"
          })
        } else {
          value = value - (el.offsetWidth / 2 - this.minSize / 2)
          el.scrollTo({
            left: value,
            behavior: "smooth"
          })
        }
      }
    },
    getItemPosByIndex(index: number) {
      let top = index * this.minSize / this.gridItems
      let result = {
        current: this.minSize,
        bottom: 0,
        top: 0,
      }
      result.top = top
      result.bottom = result.top + result.current
      return result
    },
    getBindData(defaultProp):BindData<any> {
      return {
        itemData: defaultProp.item,
        index: defaultProp.index,
        active: defaultProp.active
      }
    }
  }
})
</script>

<template>
  <el-auto-resizer>
    <template #default="{ height, width }">
      <RecycleScroller
        ref="RecycleScrollerRef"
        class="VirtualScroller"
        v-if="height>0&&width>0"
        :items="list"
        :direction="direction"
        :itemSize="fixed?minSize:null"
        :minItemSize="fixed?null:minSize"
        :itemSecondarySize="itemSecondarySize(height, width)"
        :gridItems="gridItems"
        :keyField="itemKey"
        :buffer="getBuffer()"
        :listClass="listClass"
        :itemClass="itemClass"
      >
        <template #default="defaultProp">
          <slot v-bind="getBindData(defaultProp)"></slot>
        </template>
      </RecycleScroller>
    </template>
  </el-auto-resizer>
</template>

<style scoped lang="scss">
.VirtualScroller{
  height: 100%;
  width: 100%;
}
</style>
